package business;

import java.sql.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.StringTokenizer;

import persistence.db.DataSet;
import persistence.model.AbstractModel;
import persistence.model.AnneeEtude;
import persistence.model.Conge;
import persistence.model.Seance;
import persistence.model.Semestre;
import utility.Record;
import utility.Time;

/**
 * @author Nicolas
 *
 */
public class AnneeEtudeBL {

	private AnneeEtude ae = null;
	private ArrayList<String> listeErreurs = new ArrayList<String>();
	
	
	public AnneeEtudeBL(){}
	
	public AnneeEtudeBL(int id){
		ae = (AnneeEtude) AnneeEtude.all().get(id);
	}
	
	/**
	 * @return retourne si le format de la date est valide ou non
	 */
	public boolean invalideDate(String d){	
		String strDay = d.substring(0, 2);
		String strMonth = d.substring(3,5);
		String strYear =d.substring(6,10);
		GregorianCalendar gc=new GregorianCalendar(); 
		boolean invalide = false;
		if((gc.get(Calendar.YEAR)-Integer.parseInt(strYear)) > 2 || 
				   (gc.get(Calendar.YEAR)-Integer.parseInt(strYear)) < -2 ||
				   Integer.parseInt(strMonth)>12 || Integer.parseInt(strMonth)<=0 ||
				   Integer.parseInt(strDay)>31 || Integer.parseInt(strDay)<=0)
				{
					invalide = true;
					return invalide;
				}
		else if(d.length() != 10){
			invalide = true;
			return invalide;
		}
		else{						
			SimpleDateFormat s=new SimpleDateFormat("dd/MM/yyyy");
			Date date = null;
			try{
				date = (Date) s.parse(d);
			}catch(Exception e){
				//si n'a pas reussi a transformer le string vers date, format de la date invalide
				invalide = true;
				return invalide;
			}
			String s1 = s.format(date);
			// retransformer la date vers type String, si n'est pas pareil qu'avant, logique erreur
				invalide = !d.equals(s1);
				return invalide;
			} 
	}
	
	/**
	 * @return retourne si la date debut est apres la date fin
	 */
	public boolean dateDepasse(String dateDebut, String dateFin){
		boolean dateDepasseErreur =false;
    	int yearDeb, yearFin, monthDeb, monthFin, dayDeb, dayFin;
    	
    	dateDebut = dateDebut.replace('/',' ');
    	StringTokenizer tokenizer = new StringTokenizer(dateDebut);
   	    dayDeb = Integer.parseInt(tokenizer.nextToken());
   	    monthDeb = Integer.parseInt(tokenizer.nextToken());
   	    yearDeb = Integer.parseInt(tokenizer.nextToken());
   	    
    	dateFin = dateFin.replace('/',' ');
    	tokenizer = new StringTokenizer(dateFin);
   	    dayFin = Integer.parseInt(tokenizer.nextToken());
   	    monthFin = Integer.parseInt(tokenizer.nextToken());
   	    yearFin = Integer.parseInt(tokenizer.nextToken());

   	    if (yearFin < yearDeb) {
   	    	dateDepasseErreur = true;
   	    }
   	    else if (yearFin == yearDeb && monthFin < monthDeb) {
   	    	dateDepasseErreur = true;
   	    }
   	    else if ((yearFin == yearDeb && monthFin == monthDeb && dayFin < dayDeb)) {
   	    	dateDepasseErreur = true;
   	    }
   	    return dateDepasseErreur;
	}
	
	
	/**
	 * @return retourne si la demande d'ajout ou de modification est valide ou non
	 */
	public boolean estValidePourModif(){
		boolean estValide = true;
		boolean existeDeja = false;
		
		for (AbstractModel anneeEtude : AnneeEtude.all().filter("fk_AE_formation = " + ae.getIdFormation()))
		{
			AnneeEtude aeCourant = (AnneeEtude)anneeEtude;
			if(aeCourant.getNomAnneeEtude().equals(ae.getNomAnneeEtude()) ){
				existeDeja = true;
				estValide = false;
			}
		}
		if(existeDeja){
			listeErreurs.add("Cette année étude existe déjà.");				
		}
/*		if(invalideDate(ae.getDebutAnneeEtude()) || invalideDate(ae.getFinAnneeEtude())){
			estValide = false;
			listeErreurs.add("La date n'est pas valide.");
		}
*/		if(dateDepasse(ae.getDebutAnneeEtude(), ae.getFinAnneeEtude())){
			estValide = false;
			listeErreurs.add("La date début ne peut pas dépassée la date fin.");
		}
		if(getNbSeancesaeMatin() < 0 || getNbSeancesaeAprem() < 0){
			estValide = false;
			listeErreurs.add("Le nombre d'heure doit être supérieur que 0.");		
		}
		if(getDureeSeance() < 0){
			estValide = false;
			listeErreurs.add("La durée d'une séance doit être supérieur que 0.");		
		}
		System.out.println(listeErreurs);
		return estValide;
	}
	

	/**
	 * @return retourne si la demande de suppression est valide ou non
	 */
	public boolean estValidePourSuppr(){
		boolean estValide = true;
		
		// S'il existe des semestres associes a l'annee etude a supprime, n'est pas valide
		ArrayList<Record> listeSemestre = getListeSemestre();
		if (!listeSemestre.isEmpty()) {
			listeErreurs.add("Semestres existants à cette année étude.");
			estValide = false;
		} else {
			estValide = true;
		}
		System.out.println(estValide);
		return estValide;
	}
	
	/**
	 * @param id : identifiant d'année d'étude
	 * @param nom : nom de l'année d'étude
	 * @param desc : description de l'année d'étude
	 * @param debut : date de début de l'année d'étude
	 * @param fin : date de fin de l'année d'étude
	 * @param nbSeancesMatin : nombre de seances du matin
	 * @param nbSeancesAprem : nombre de seances de l'après midi
	 * @param dureeSeance : durée d'une séance
	 */
	public ArrayList<String> ajouterAnneeEtude(int id, String nom, String desc, String debut, String fin, int nbSeancesMatin, int nbSeancesAprem, int dureeSeance, int idFormation, DataSet dsSemestre) {
		ae = new AnneeEtude(id, nom, desc, debut, fin, nbSeancesMatin, nbSeancesAprem, dureeSeance, idFormation, dsSemestre);
		ArrayList<String> listeErreurs = new ArrayList<String>();
		if (this.estValidePourModif()) {
			ae.save();
		} 
		return listeErreurs;
	}
	
	/**
	 * @param id : identifiant d'année d'étude
	 * @param nom : nom de l'année d'étude
	 * @param desc : description de l'année d'étude
	 * @param debut : date de début de l'année d'étude
	 * @param fin : date de fin de l'année d'étude
	 * @param nbSeancesMatin : nombre de seances du matin
	 * @param nbSeancesAprem : nombre de seances de l'après midi
	 * @param dureeSeance : durée d'une séance
	 */
	public ArrayList<String> modifierAnneeEtude(int id, String nom, String desc, String debut, String fin, int nbSeancesMatin, int nbSeancesAprem, int dureeSeance, int idFormation, DataSet dsSemestre) {
		ae = new AnneeEtude(id, nom, desc, debut, fin, nbSeancesMatin, nbSeancesAprem, dureeSeance, idFormation, dsSemestre);
		ArrayList<String> listeErreurs = new ArrayList<String>();
//		if (this.estValidePourModif()) {
			ae.save(id);
//		} 
		return listeErreurs;
	}
	

	public ArrayList<String> supprimerAnneeEtude() {
		ArrayList<String> listeErreurs = new ArrayList<String>();
		if (this.estValidePourSuppr()) {
			ae.delete();
		}
		return listeErreurs;
	}
	
	
	/* Ensemble des getters et setters -> delegation vers la persistance */

	public String getNomAnneeEtude() {
		return ae.getNomAnneeEtude();
	}

	public void setNomAnneeEtude(String nomAnneeEtude) {
		ae.setNomAnneeEtude(nomAnneeEtude);
	}

	public String getDescriptionAnneeEtude() {
		return ae.getDescriptionAnneeEtude();
	}

	public void setDescriptionAnneeEtude(String descriptionAnneeEtude) {
		ae.setDescriptionAnneeEtude(descriptionAnneeEtude);
	}

	public String getDebutAnneeEtude() {
		return ae.getDebutAnneeEtude();
	}

	public void setDebutAnneeEtude(String debutAnneeEtude) {
		ae.setDebutAnneeEtude(debutAnneeEtude);
	}

	public String getFinAnneeEtude() {
		return ae.getFinAnneeEtude();
	}

	public void setFinAnneeEtude(String finAnneeEtude) {
		ae.setFinAnneeEtude(finAnneeEtude);
	}

	public int getNbSeancesaeMatin() {
		return ae.getNbSeancesAEMatin();
	}

	public void setNbSeancesaeMatin(int nbSeancesaeMatin) {
		ae.setNbSeancesAEMatin(nbSeancesaeMatin);
	}

	public int getNbSeancesaeAprem() {
		return ae.getNbSeancesAEAprem();
	}

	public void setNbSeancesaeAprem(int nbSeancesaeAprem) {
		ae.setNbSeancesAEAprem(nbSeancesaeAprem);
	}

	public int getDureeSeance() {
		return ae.getDureeSeance();
	}

	public void setDureeSeance(int dureeSeance) {
		ae.setDureeSeance(dureeSeance);
	}

	public int getIdAnneeEtude(){
		return ae.getId();
	}
	
	public void setIdAnneeEtude(int idAnneeEtude){
		ae.setId(idAnneeEtude);
	}
	public int getIdFormation(){
		return ae.getIdFormation();
	}
	
	public void setIdFormation(int idFormation){
		ae.setId(idFormation);
	}
	
	public DataSet getSemestresSet(){
		return ae.getSemestresSet();
	}
	
	public void setSemestresSet(DataSet dsSem){
		ae.setSemestresSet(dsSem);
	}
	

	/**
	 * @return : la liste des semestres de l'année d'étude concernée
	 */
	public ArrayList<Record> getListeSemestre()
	{
		ArrayList<Record> listeSemestres = new ArrayList<Record>();
		
		for (AbstractModel s : ae.getSemestresSet())
		{
			Semestre semestreCourant = (Semestre)s;
			
			int semestreId = semestreCourant.getId();

			String semestreNom = semestreCourant.getNomSemestre();
			
			listeSemestres.add(new Record(semestreId, semestreNom));
		}
		
		return listeSemestres;
	}
	
	/**
	 * @param idAnneeEtude : identifiant de l'année d'étude 
	 * @return : la liste des congés de l'année d'étude concernée
	 */
	public ArrayList<Record> getListeConge(int idAnneeEtude)
	{
		ArrayList<Record> listeConge = new ArrayList<Record>();
		
		for (AbstractModel conge : Conge.all().filter("fk_conge_AE = " + ae.getId()))
		{
			Conge congeCourant = (Conge)conge;
			
			int idConge = congeCourant.getId();
			String dateDebutConge = congeCourant.getDateDebutConge();
			String dateFinConge = congeCourant.getDateFinConge();
			String dateDebutFinConge = dateDebutConge.toString() + " - " + dateFinConge.toString();
			listeConge.add(new Record(idConge, dateDebutFinConge));
		}
		
		return listeConge;
	}
	
	public ArrayList<SeanceBL> getListeSeances(int idPeriode) {
		ArrayList<SeanceBL> resultSeance = new ArrayList<SeanceBL>();

		for (AbstractModel seance : Seance.all().filter("fk_seance_periode = " + idPeriode))
		{
			AnneeEtude ae = ((Seance)seance).getService().getSEE().getMatiere().getUE().getSemestre().getAnneeEtude();
			if(ae.getId() == this.getIdAnneeEtude()){
				resultSeance.add(new SeanceBL(((Seance) seance).getId()));
			}
		}
		
		return resultSeance;
	}
	
}